﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace jSLCore.Client.Utility
{
    /// <summary>
    /// Помошник для работы с SilverLight
    /// </summary>
    public static partial class UIHelper
    {
        /// <summary>
        /// Проверяка, если в VisualTree вверх есть указанные parent
        /// </summary>
        public static bool IsImplicitParent(this FrameworkElement element, UIElement parent,bool includeTemplatedParent = true)
        {
            return IsImplicitParent(element, parent, false, includeTemplatedParent);
        }

        /*/// <summary>
        /// Проверяка, если в VisualTree вверх есть указанные parent
        /// </summary>
        public static bool IsImplicitParent(this FrameworkElement element, UIElement parent)
        {
            return IsImplicitParent(element,parent,false,true);
        }
*/
        private static bool IsImplicitParent(this FrameworkElement element, UIElement parent,bool includeThis,bool includeTemplatedParent)
        {
            if(parent==null) throw new InvalidOperationException("Агрумент parent не может быть Null");

            if(includeThis)
                if (element == parent) return true;

            bool val=false;
            if(element.Parent!=null) val = IsImplicitParent((FrameworkElement) element.Parent, parent, true,includeTemplatedParent);


            if(!val && includeTemplatedParent)
            {
                var visParent = VisualTreeHelper.GetParent(element);
                if(visParent!=null)
                val = IsImplicitParent((FrameworkElement) visParent, parent,true,includeTemplatedParent);
            }

            return val;

        }

      /*  public static FrameworkElement FindAncestor(this FrameworkElement element,Type type)
        {
        //    if (element == null) return null;
            if (type == null) throw new InvalidOperationException("Агрумент type не может быть Null");


            VisualTreeHelper.GetParent(pa)

            if (element.Parent == null) return null;
            if (element.Parent.GetType().IsSubclassOf(type) || element.Parent.GetType()==type) return (FrameworkElement) element.Parent;

            var parentElement = element.Parent as FrameworkElement;
            if (parentElement != null) return parentElement.FindAncestor(type);
            else return null;
        }*/

        
        public static T FindAncestor<T>(this FrameworkElement element) where T : DependencyObject
        {
            return element.FindAncestorUpstairs<T>(false,true);
        }

        public static T FindAncestor<T>(this FrameworkElement element, bool useTemplatedParent) where T : DependencyObject
        {
            return element.FindAncestorUpstairs<T>(false, useTemplatedParent);
        }

        private static T FindAncestorUpstairs<T>(this DependencyObject element, bool includeThis,bool useTemplatedParent) where T : DependencyObject
        {
            if (element == null) return null;
            //if (type == null) throw new InvalidOperationException("Агрумент type не может быть Null");

             /*if(includeThis)
                if (element.GetType() == type || element.GetType().IsSubclassOf(type)) return element;*/

             if (includeThis)
                 if (element.GetType() == typeof(T) || element.GetType().IsSubclassOf(typeof(T)))
                     return (T)element;

             if (element is FrameworkElement && ((FrameworkElement)element).Parent != null)
             {
                 var searchIt = ((FrameworkElement)element).Parent.FindAncestorUpstairs<T>(true,useTemplatedParent);
                 if (searchIt != null) return searchIt;
             }

             if (!useTemplatedParent) return null;

             var parent2 = VisualTreeHelper.GetParent(element);
             return parent2.FindAncestorUpstairs<T>(true,true);

/*
             if (VisualTreeHelper.GetParent(element)/*.Parent ♥1♥== null) return null;
            if (VisualTreeHelper.GetParent(element)/*.Parent♥1♥.GetType().IsSubclassOf(type) || VisualTreeHelper.GetParent(element)/*.Parent♥1♥.GetType() == type) return (FrameworkElement)VisualTreeHelper.GetParent(element)/*.Parent♥1♥;

            var parentElement = VisualTreeHelper.GetParent(element)/*.Parent♥1♥ as FrameworkElement;
            if (parentElement != null) return parentElement.FindAncestor(type);
             try
             {
                 var templParent = element.GetType().GetProperty("TemplatedParent",BindingFlags.NonPublic);
                 var parent = templParent.GetValue(element,new object[0]) as FrameworkElement;
                 if(parent!=null && (parent.GetType()==type || parent.GetType().IsSubclassOf(type))) return  parent;
                 return parent.FindAncestor(type);
             }
             catch (Exception)
             {
                 return null;
             }*/
        }
    }
}